/*----------------------------------------------------
Class: plant_1DSOS_RDM_input_1Dsin
DESCRIPTION:
  This class implements random deposition(RD) with migration(M). The lattice
  is 1D solid-on-solid(SOS).

REFERENCE/BASED ON:
  n_sos_2D_L200_T650.c by Gangshi and Jianqiao
  sos_2d_L100_T700.c

INPUT:
 0 T: Temperature, K
 1 W: deposition rate, layer/s
 2 A: 
 3 K: 
OUTPUT:
 0 H: average height, layer
 1 R2: roughness square, layer^2
 2 M2: RMS slope square, dimensionless
 3 a: auto-correlation length
STATE:
 * lattice: a 1D array save the height profile.
OPTIONS:
 * 

AUTHOR: Xinyu Zhang (zxy1256@gmail.com)
----------------------------------------------------*/
#ifndef plant_1DSOS_RDM_INPUT_1DSIN_H
#define plant_1DSOS_RDM_INPUT_1DSIN_H

#include "Signal.h"

const double EV2KB = 11608.696;
const double KB2H  = 2.08144796e10;
const int    NUMBER_NEIGHBOR = 3;

typedef unsigned int index_t;

class plant_1DSOS_RDM_input_1Dsin:public block
{
private:
  // Options
  int    Lx;
  int    N_CL;
  int    mode;
  double E_D;
  double E_S;
  double E_N;
	
  // Inputs
  double W;
  double Freq;
  double A;
  double T;

  // States
  int*      height;
  int*      num_lower_neigh;
  
  MCArray*  migration_events;
  MCArray*  desorption_events;
  MCArray*  adsorption_events;
  MCArray*  ads_mig_des;

  // double rate_ttl,ads_ttl,migr_ttl,desorp_ttl;
  double MIGR_RT[5];
  double DESORP_RT[5];
  double k_m2d;

  // Outputs
  double h;
  double r2;
  double m2;
  double a;

  // GSL random generator
  const	gsl_rng_type *gsl_T;
  gsl_rng *gsl_r;

  void add_remove_atom(int x,int num);
  void adsorption();
  void migration();
  void desorption();
  double OneMCTime(double r_d);
  void migr_site(int *migr_x);
  void desorp_site(int *desorp_x);
  void set_ads_rate(double W_set,double Freq_set,double A_set);
  void set_temperature(double T_set);
//  void GetNeighbors(int x, int *xpos);	
  void init_migr_rate();
  void init_desorp_rate();
//  void init_local_stat(int x, int y);
  int  Num_Higher_Neighbors(int x);
  inline int left_neigh(int x){assert(x>=0 && x<Lx); return (x==0)?Lx-1:x-1;};
  inline int right_neigh(int x){assert(x>=0 && x<Lx); return (x==Lx-1)?0:x+1;};

  // The following declaration is to prevent compiler default implementation.
  plant_1DSOS_RDM_input_1Dsin(const plant_1DSOS_RDM_input_1Dsin&);
  plant_1DSOS_RDM_input_1Dsin& operator=(const plant_1DSOS_RDM_input_1Dsin&);
public:
  plant_1DSOS_RDM_input_1Dsin(double idt, int iLx=100,int iMode = 50,double iE_D = 1.8,double iE_S = 1.2,double iE_N=0.6);
  plant_1DSOS_RDM_input_1Dsin(const string FileName);
  ~plant_1DSOS_RDM_input_1Dsin();
	
  // The virtual/overrided functions, used with SIMULATION framework
  virtual void update(double sysTime);
  virtual void reset();

  // void   getSnapshot(const string FileName);
  double getM2();
  double getR2();
  double getH();
  double getTime(){return time;};
  double getAutoCorLength();
  void   getXCov(const string filename);
  void   getSnapshot(const string filename);
};

#endif
